package com.linsen.gateway.handler;

import cn.dev33.satoken.annotation.SaMode;
import cn.dev33.satoken.filter.SaFilterAuthStrategy;
import cn.dev33.satoken.router.SaRouter;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.linsen.core.satoken.constant.SaTokenConstant;
import com.linsen.gateway.initializer.ApiResourcesMapping;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.Map;

/**
 * 鉴权方法：每次访问进入
 *
 * @author zhaoyong
 * @date 2023/8/4
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class SaTokenAuthHandler implements SaFilterAuthStrategy {
    @Override
    public void run(Object o) {
        SaRouter.match(SaTokenConstant.ENDPOINTS).stop();
        Map<String, ApiResourcesMapping> mappings = SaTokenApiResourcesMappingHandler.getMappings();
        for (Map.Entry<String, ApiResourcesMapping> apiResourcesMappingEntry : mappings.entrySet()) {
            String key = apiResourcesMappingEntry.getKey();
            ApiResourcesMapping value = apiResourcesMappingEntry.getValue();
            if (ObjectUtil.isNull(value)) {
                continue;
            }

            if (BooleanUtil.isFalse(value.getCheckLogin())) {
                SaRouter.match(key).stop();
            }

            if (ArrayUtil.isNotEmpty(value.getCodes())) {
                if (SaMode.AND.equals(value.getMode())) {
                    SaRouter.match(key, r -> StpUtil.checkPermissionAnd(value.getCodes()));
                }

                if (SaMode.OR.equals(value.getMode())) {
                    SaRouter.match(key, r -> StpUtil.checkPermissionOr(value.getCodes()));
                }
            }

            if (ArrayUtil.isNotEmpty(value.getRoles())) {
                if (SaMode.AND.equals(value.getMode())) {
                    SaRouter.match(key, r -> StpUtil.checkRoleAnd(value.getRoles()));
                }

                if (SaMode.OR.equals(value.getMode())) {
                    SaRouter.match(key, r -> StpUtil.checkRoleOr(value.getRoles()));
                }
            }
        }

        // 登录校验
        SaRouter.match("/**").check(r -> StpUtil.checkLogin());
    }
}
